import os
import datetime
import logging
from logging.handlers import RotatingFileHandler

# 日志级别    数值
# CRITICAL    50
# ERROR       40
# WARNING     30
# INFO        20
# DEBUG       10
# NOTSET       0


class LoggingConfig:
    BASE_DIR = os.getcwd()
    LOGS_DIR = os.path.join(BASE_DIR, "logs")

    if os.path.exists(LOGS_DIR):
        pass
    else:
        os.makedirs("logs")
    dateNowTime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # 创建handler,将日志输出到文件
    fileHandler = logging.FileHandler("logs/message.log", encoding="UTF-8")
    # 设置日志记录最低级别为DEBUG，低于DEBUG级别的日志记录会被忽略，不设置setLevel()则默认为NOTSET级别。
    fileHandler.setLevel(logging.DEBUG)
    # 设置handler打印格式
    logging_format = logging.Formatter(
        "%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s"
    )
    # logging_format = logging.Formatter(
    #     "时间:%(asctime)s 日志级别值:%(levelno)s 日志级别:%(levelname)s 当前执行程序的路径:%(pathname)s 当前执行程序名:%(filename)s 当前函数%(funcName)s 当前行号%(lineno)d 线程 ID:%(thread)d 线程名称:%(threadName)s 进程 ID:%(process)d 线程名称:%(processName)s 模块名称:%(module)s 日志信息:%(message)s"
    # )
    fileHandler.setFormatter(logging_format)

    # 创建handler,将日志输出到文件
    # RotatingFileHandler日志处理器，用于记录日志到文件，并支持日志文件按大小和数量自动切割，实现日志轮转（即备份旧日志文件并创建新日志)
    # 其参数：filename：文件名，指定日志文件的路径和名称。
    # mode：模式，可选值为'a'（追加）和'w'（覆盖）。
    # encoding：编码方式，指定日志文件的字符编码。
    # backupCount：备份文件的数量，指定自动切割日志文件时最多保留的备份文件数量，默认值为0，即不保留任何备份文件。
    # maxBytes：每个日志文件的最大大小（以字节为单位），当日志文件达到该大小时，会自动备份旧日志并创建新日志文件，默认值为0，即不限制每个日志文件的大小。dalay: 是否开启异步写入(延时打开文件)，默认为False，表示初始化时即打开日志文件同步写入，当为True时，表示日志记录时异步写入,即在第一次写入时才打开日志文件，提高性能。
    rotatingFileHandler = RotatingFileHandler(
        "logs/message1.log",
        maxBytes=100 * 1024 * 1024,
        backupCount=10,
        encoding="UTF-8",
    )
    rotatingFileHandler.setLevel(logging.DEBUG)
    fmt_str = logging.Formatter(
        "时间:%(asctime)-15s 日志级别:%(levelname)s 文件名:%(filename)s 函数名:%(funcName)s 行数:%(lineno)d 进程号:%(process)d 当前线程号:%(thread)s 日志信息:%(message)s"
    )
    rotatingFileHandler.setFormatter(fmt_str)
    # TimedRotatingFileHandler 日志处理器，与 RotatingFileHandler类似，也用于将日志写入到指定的文件中，并对文件进行切割。不同的是TimedRotatingFileHandler 可以按照时间轮转日志，例如每天或每小时生成一个新的日志文件。
    # Class logging.handlers.TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None)
    # 参数的详解：
    # filename：文件名，指定日志文件的路径和名称；
    # when：日志轮转的时间间隔，可选值为 'S'、'M'、'H'、'D'、'W'和 'midnight'，分别表示秒、分、时、天、周和每天的午夜；默认值为'midnight'，即每天的午夜轮转，值不区分大小写；
    # interval：时间间隔的数量，默认为 1；例如，当 when='D'且 interval=7 时，表示每周轮转一次；
    # backupCount：备份文件数目；当生成的日志文件数量超过该数目时，会自动删除旧的备份日志文件；默认值为 0，表示不备份；
    # encoding：日志文件的编码格式，默认为 None，表示使用系统默认编码；
    # delay：是否延时打开文件，可选值为 True 和 False；当为 True 时，表示延时打开文件，即在第一次写入日志时才打开日志文件；当为 False时，表示在初始化时即打开日志文件；默认值为 False；
    # utc：是否使用 UTC 时间，默认为 False，表示使用本地时间
    # atTime：用来设置轮转时间，格式为 '%H:%M:%S'，默认为午夜 12点；需要注意的是该参数仅在when为W/midnight时有效；

    # 日志配置中添加StreamHandler，可以将日志输出到屏幕上
    consoleHandler = logging.StreamHandler()
    consoleHandler.setLevel(logging.DEBUG)
    consoleFormatter = logging.Formatter(
        "%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - 进程号:%(process)d 当前线程号:%(thread)s - %(message)s"
    )
    consoleHandler.setFormatter(consoleFormatter)

    # 创建一个logger对象
    logger = logging.getLogger()
    # 添加handlers到logger
    logger.addHandler(fileHandler)
    # 添加handlers到logger
    logger.addHandler(rotatingFileHandler)
    # 添加handlers到logger
    logger.addHandler(consoleHandler)


# 日志内容测试二
if __name__ == "__main__":
    try:
        LoggingConfig.logger.info("info message：输出 m =1/0")
        m = 1 / 0
    except Exception as e:
        LoggingConfig.logger.error("error message")
